
package com.probiz.estore.order.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.springframework.util.Assert;

import com.probiz.estore.common.model.order.OrderShipment;
import com.probiz.estore.common.model.order.SalesOrder;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.service.impl.GenericManagerImpl;
import com.probiz.estore.core.util.StringUtil;
import com.probiz.estore.order.dao.SalesOrderDao;
import com.probiz.estore.order.model.OrderSearchCriteria;
import com.probiz.estore.order.service.SalesOrderManager;
import com.probiz.estore.system.service.MsgSendManager;
import com.probiz.estore.system.util.MsgTemplateConstants;

/**
 * Manager implementation for SalesOrder, responsible for business processing,
 * and communicate between web and persistence layer.
 */
public class SalesOrderManagerImpl extends GenericManagerImpl<SalesOrder>
		implements SalesOrderManager {

	private SalesOrderDao		salesOrderDao		= null;

	private MsgSendManager msgSendManager = null;

	public void setSalesOrderDao(SalesOrderDao salesOrderDao) {
		this.salesOrderDao = salesOrderDao;
	}

	public void setMsgSendManager(MsgSendManager msgSendManager) {
		this.msgSendManager = msgSendManager;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#init()
	 */
	@Override
	protected void initManager() {
		dao = salesOrderDao;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#preDelete(java.lang.Object)
	 */
	@Override
	protected void preDelete(SalesOrder entity) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#preSave(java.lang.Object)
	 */
	@Override
	protected void preSave(SalesOrder entity) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.order.service.SalesOrderManager#searchByCriteria(com.probiz.estore.order.model.OrderSearchCriteria,
	 *      com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<SalesOrder> searchByCriteria(
			OrderSearchCriteria orderSearchCriteria,
			SearchCriteria searchCriteria) {
		return salesOrderDao.searchByCriteria(orderSearchCriteria,
				searchCriteria);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.order.service.SalesOrderManager#searchByCriteriaForController(com.probiz.estore.order.model.OrderSearchCriteria,
	 *      com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<SalesOrder> searchByCriteriaForController(
			OrderSearchCriteria orderSearchCriteria,
			SearchCriteria searchCriteria) {
		if (searchCriteria.getPageNo() < 1) // 如果是翻页过前，就拿第一页就可以。
		{
			searchCriteria.changePaging(1, searchCriteria.getPageSize());
		}
		List<SalesOrder> result = searchByCriteria(orderSearchCriteria,
				searchCriteria);
		if (result == null || result.size() == 0) {
			if (searchCriteria.getPageNo() > searchCriteria.getTotalPageCount()) // 如果是翻页前，就拿最后一页就可以。
			{
				searchCriteria.changePaging(searchCriteria.getTotalPageCount(),
						searchCriteria.getPageSize());
				result = searchByCriteria(orderSearchCriteria, searchCriteria);
			}
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.order.service.SalesOrderManager#getSalesOrderByOrderNo(String)
	 */
	public SalesOrder getSalesOrderByOrderNo(String orderNo) {
		return this.salesOrderDao.getUniqueByProperty("orderNo", orderNo);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.order.service.SalesOrderManager#countCustomerOrder(java.lang.Integer)
	 */
	public long countCustomerOrder(Integer userId) {
		Assert.notNull(userId);
		return salesOrderDao.countCustomerOrder(new Integer(userId.toString()),
				false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.order.service.SalesOrderManager#countCustomerOrder(java.lang.Integer,
	 *      java.lang.Short)
	 */
	public long countCustomerOrder(Integer userId, Short orderStatus) {
		return this.salesOrderDao.countCustomerOrder(userId, orderStatus);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#countUnPaidSalesOrder(java.lang.Integer)
	 */
	public Long countUnPaidSalesOrder(Integer customerId){
		return salesOrderDao.countUnPaidSalesOrder(customerId);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#getCustomerConsumption(java.lang.Integer, java.util.Date, java.util.Date)
	 */
	public BigDecimal getCustomerConsumption(Integer userId,
			Date startDate, Date endDate) {
		return this.salesOrderDao.getCustomerConsumption(userId, startDate,
				endDate);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#sendEmail4PlaceOrder(com.probiz.estore.common.model.order.SalesOrder)
	 */
	public void sendEmail4PlaceOrder(SalesOrder salesOrder) {
		Map<String, Object> map = new HashMap<String, Object>();
		if(null == salesOrder.getCustomerFullName()){
			salesOrder.setCustomerFirstname(salesOrder.getOrderAddress().getFirstname());
		}
		map.put("salesOrder", salesOrder);
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_PLACING_AN_ORDER, map, new String[] { salesOrder.getOrderAddress().getEmail() }, salesOrder.getCustomerId() == null ? null : new String[]{salesOrder.getCustomerId().toString()}, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#sendEmail4Ship(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.common.model.order.OrderShipment)
	 */
	public void sendEmail4Ship(SalesOrder salesOrder,OrderShipment orderShipment){
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("salesOrder", salesOrder);
		map.put("orderShipment", orderShipment);
		try {
			//mailEngine.sendSimpleTemplateMail("/order/orderShip.vm" , map,	null, from, new String[] { salesOrder.getOrderAddress().getEmail() });
			msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_SHIPMENTS, map, new String[] { salesOrder.getOrderAddress().getEmail() }, salesOrder.getCustomerId() == null ? null : new String[]{salesOrder.getCustomerId().toString()}, new String[] {salesOrder.getOrderAddress().getPhoneNumber()});
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#countNewArrivalOrder()
	 */
	public Long countNewArrivalOrder() {
		return this.salesOrderDao.countNewArrivalOrder();
	}

	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#getLastSalesOrder(java.lang.Integer)
	 */
	public SalesOrder getLastSalesOrder(Integer customerId) {
		return this.salesOrderDao.getLastSalesOrder(customerId);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#countOrderTotal()
	 */
	public Long countOrderTotal() {
		return salesOrderDao
				.countByFilter(SalesOrder.FilterHqlName.ORDER_TOTAL);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#getSalesOrder4Export(java.util.Date)
	 */
	public List<SalesOrder> getSalesOrder4Export(Date latestExportTime) {
		return this.salesOrderDao.getSalesOrder4Export(latestExportTime);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#countOrderTotalByProductIdByOrderStatuses(java.lang.Integer, java.lang.Short[])
	 */
	public Long countOrderTotalByProductIdByOrderStatuses(Integer productId,Short[] orderStatuses){
		StringBuffer sb = new StringBuffer();
		sb.append("from SalesOrder o where 1=1 ");
		if(!ArrayUtils.isEmpty(orderStatuses)){
			String multiObjString = StringUtil.shortArrayToString(orderStatuses, ",");
			sb.append(" and o.orderStatus in ("+multiObjString+")");
		}
		sb.append("and o.salesOrderId in (select os.salesOrder.salesOrderId from OrderSku os where os.productId = ? )");
		return salesOrderDao.countByHql(sb.toString(),productId);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#countOrderTotalByProductSkuIdByOrderStatuses(java.lang.Integer, java.lang.Short[])
	 */
	public Long countOrderTotalByProductSkuIdByOrderStatuses(Integer productSkuId,Short[] orderStatuses){
		StringBuffer sb = new StringBuffer();
		sb.append("from SalesOrder o where 1=1 ");
		if(!ArrayUtils.isEmpty(orderStatuses)){
			String multiObjString = StringUtil.shortArrayToString(orderStatuses, ",");
			sb.append(" and o.orderStatus in ("+multiObjString+")");
		}
		sb.append("and o.salesOrderId in (select os.salesOrder.salesOrderId from OrderSku os where os.productSku.productSkuId = ? )");
		return salesOrderDao.countByHql(sb.toString(),productSkuId);
	}
	
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#getSizeByOrderNo(java.lang.String)
	 */
	public Long getSizeByOrderNo(String orderNo){
		return salesOrderDao.countByHql("from SalesOrder o where o.orderNo = ?", orderNo);
	}
	/* (non-Javadoc)
	 * @see com.probiz.estore.order.service.SalesOrderManager#countOrderTotalByGiftIdByOrderStatuses(java.lang.Integer, java.lang.Short[])
	 */
	public Long countOrderTotalByGiftIdByOrderStatuses(Integer giftId, Short[] orderStatuses){
		StringBuffer sb = new StringBuffer();
		sb.append("from SalesOrder o where 1=1 ");
		if (!ArrayUtils.isEmpty(orderStatuses)) {
			String multiObjString = StringUtil.shortArrayToString(orderStatuses, ",");
			sb.append(" and o.orderStatus in ("+multiObjString+")");
		}
		sb.append("and o.salesOrderId in (select os.salesOrder.salesOrderId from OrderSku os where os.gift.giftId = ? )");
		return salesOrderDao.countByHql(sb.toString(),giftId);
	}
}
